home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / gfx / x11 / twm_930531.lha / twm / iconmgr.c < prev    next >
C/C++ Source or Header  |  1993-05-30  |  19KB  |  767 lines

  1. /*
  2.  * Copyright 1989 Massachusetts Institute of Technology
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and its
  5.  * documentation for any purpose and without fee is hereby granted, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of M.I.T. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  M.I.T. makes no representations about the
  11.  * suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  15.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  16.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  17.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  18.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  19.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  20.  */
  21.  
  22. /***********************************************************************
  23.  *
  24.  * $XConsortium: iconmgr.c,v 1.47 91/07/12 09:59:42 dave Exp $
  25.  *
  26.  * Icon Manager routines
  27.  *
  28.  * 09-Mar-89 Tom LaStrange        File Created
  29.  *
  30.  ***********************************************************************/
  31.  
  32. #include <stdio.h>
  33. #include "twm.h"
  34. #include "util.h"
  35. #include "parse.h"
  36. #include "screen.h"
  37. #include "resize.h"
  38. #include "add_window.h"
  39. #include "siconify.bm"
  40. #include <X11/Xos.h>
  41. #include <X11/Xmu/CharSet.h>
  42. #ifdef macII
  43. int strcmp(); /* missing from string.h in AUX 2.0 */
  44. #endif
  45.  
  46. int iconmgr_textx = siconify_width+11;
  47. WList *Active = NULL;
  48. WList *DownIconManager = NULL;
  49. int iconifybox_width = siconify_width;
  50. int iconifybox_height = siconify_height;
  51.  
  52. /***********************************************************************
  53.  *
  54.  *  Procedure:
  55.  *    CreateIconManagers - creat all the icon manager windows
  56.  *        for this screen.
  57.  *
  58.  *  Returned Value:
  59.  *    none
  60.  *
  61.  *  Inputs:
  62.  *    none
  63.  *
  64.  ***********************************************************************
  65.  */
  66.  
  67. void CreateIconManagers()
  68. {
  69.     IconMgr *p;
  70.     int mask;
  71.     char str[100];
  72.     char str1[100];
  73.     Pixel background;
  74.     char *icon_name;
  75.  
  76.     if (Scr->NoIconManagers)
  77.     return;
  78.  
  79.     if (Scr->siconifyPm == None)
  80.     {
  81.     Scr->siconifyPm = XCreatePixmapFromBitmapData(dpy, Scr->Root,
  82.         (char *)siconify_bits, siconify_width, siconify_height, 1, 0, 1);
  83.     }
  84.  
  85.     for (p = &Scr->iconmgr; p != NULL; p = p->next)
  86.     {
  87.     mask = XParseGeometry(p->geometry, &JunkX, &JunkY,
  88.                   (unsigned int *) &p->width, (unsigned int *)&p->height);
  89.  
  90.     if (mask & XNegative)
  91.         JunkX = Scr->MyDisplayWidth - p->width - 
  92.           (2 * Scr->BorderWidth) + JunkX;
  93.  
  94.     if (mask & YNegative)
  95.         JunkY = Scr->MyDisplayHeight - p->height -
  96.           (2 * Scr->BorderWidth) + JunkY;
  97.  
  98.     background = Scr->IconManagerC.back;
  99.     GetColorFromList(Scr->IconManagerBL, p->name, (XClassHint *)NULL,
  100.              &background);
  101.  
  102.     p->w = XCreateSimpleWindow(dpy, Scr->Root,
  103.         JunkX, JunkY, p->width, p->height, 1,
  104.         Scr->Black, background);
  105.  
  106.     sprintf(str, "%s Icon Manager", p->name);
  107.     sprintf(str1, "%s Icons", p->name);
  108.     if (p->icon_name)
  109.         icon_name = p->icon_name;
  110.     else
  111.         icon_name = str1;
  112.  
  113.     XSetStandardProperties(dpy, p->w, str, icon_name, None, NULL, 0, NULL);
  114.  
  115.     p->twm_win = AddWindow(p->w, TRUE, p);
  116.     SetMapStateProp (p->twm_win, WithdrawnState);
  117.     }
  118.     for (p = &Scr->iconmgr; p != NULL; p = p->next)
  119.     {
  120.     GrabButtons(p->twm_win);
  121.     GrabKeys(p->twm_win);
  122.     }
  123. }
  124.  
  125. /***********************************************************************
  126.  *
  127.  *  Procedure:
  128.  *    AllocateIconManager - allocate a new icon manager
  129.  *
  130.  *  Inputs:
  131.  *    name    - the name of this icon manager
  132.  *    icon_name - the name of the associated icon
  133.  *    geom    - a geometry string to eventually parse
  134.  *    columns    - the number of columns this icon manager has
  135.  *
  136.  ***********************************************************************
  137.  */
  138.  
  139. IconMgr *AllocateIconManager(name, icon_name, geom, columns)
  140.     char *name;
  141.     char *geom;
  142.     char *icon_name;
  143.     int columns;
  144. {
  145.     IconMgr *p;
  146.  
  147. #ifdef DEBUG_ICONMGR
  148.     fprintf(stderr, "AllocateIconManager\n");
  149.     fprintf(stderr, "  name=\"%s\" icon_name=\"%s\", geom=\"%s\", col=%d\n",
  150.     name, icon_name, geom, columns);
  151. #endif
  152.  
  153.     if (Scr->NoIconManagers)
  154.     return NULL;
  155.  
  156.     p = (IconMgr *)malloc(sizeof(IconMgr));
  157.     p->name = name;
  158.     p->icon_name = icon_name;
  159.     p->geometry = geom;
  160.     p->columns = columns;
  161.     p->first = NULL;
  162.     p->last = NULL;
  163.     p->active = NULL;
  164.     p->scr = Scr;
  165.     p->count = 0;
  166.     p->x = 0;
  167.     p->y = 0;
  168.     p->width = 150;
  169.     p->height = 10;
  170.  
  171.     Scr->iconmgr.lasti->next = p;
  172.     p->prev = Scr->iconmgr.lasti;
  173.     Scr->iconmgr.lasti = p;
  174.     p->next = NULL;
  175.  
  176.     return(p);
  177. }
  178.  
  179. /***********************************************************************
  180.  *
  181.  *  Procedure:
  182.  *    MoveIconManager - move the pointer around in an icon manager
  183.  *
  184.  *  Inputs:
  185.  *    dir    - one of the following:
  186.  *            F_FORWICONMGR    - forward in the window list
  187.  *            F_BACKICONMGR    - backward in the window list
  188.  *            F_UPICONMGR    - up one row
  189.  *            F_DOWNICONMGR    - down one row
  190.  *            F_LEFTICONMGR    - left one column
  191.  *            F_RIGHTICONMGR    - right one column
  192.  *
  193.  *  Special Considerations:
  194.  *    none
  195.  *
  196.  ***********************************************************************
  197.  */
  198.  
  199. void MoveIconManager(dir)
  200.     int dir;
  201. {
  202.     IconMgr *ip;
  203.     WList *tmp = NULL;
  204.     int cur_row, cur_col, new_row, new_col;
  205.     int row_inc, col_inc;
  206.     int got_it;
  207.  
  208.     if (!Active) return;
  209.  
  210.     cur_row = Active->row;
  211.     cur_col = Active->col;
  212.     ip = Active->iconmgr;
  213.  
  214.     row_inc = 0;
  215.     col_inc = 0;
  216.     got_it = FALSE;
  217.  
  218.     switch (dir)
  219.     {
  220.     case F_FORWICONMGR:
  221.         if ((tmp = Active->next) == NULL)
  222.         tmp = ip->first;
  223.         got_it = TRUE;
  224.         break;
  225.  
  226.     case F_BACKICONMGR:
  227.         if ((tmp = Active->prev) == NULL)
  228.         tmp = ip->last;
  229.         got_it = TRUE;
  230.         break;
  231.  
  232.     case F_UPICONMGR:
  233.         row_inc = -1;
  234.         break;
  235.  
  236.     case F_DOWNICONMGR:
  237.         row_inc = 1;
  238.         break;
  239.  
  240.     case F_LEFTICONMGR:
  241.         col_inc = -1;
  242.         break;
  243.  
  244.     case F_RIGHTICONMGR:
  245.         col_inc = 1;
  246.         break;
  247.     }
  248.  
  249.     /* If got_it is FALSE ast this point then we got a left, right,
  250.      * up, or down, command.  We will enter this loop until we find
  251.      * a window to warp to.
  252.      */
  253.     new_row = cur_row;
  254.     new_col = cur_col;
  255.  
  256.     while (!got_it)
  257.     {
  258.     new_row += row_inc;
  259.     new_col += col_inc;
  260.     if (new_row < 0)
  261.         new_row = ip->cur_rows - 1;
  262.     if (new_col < 0)
  263.         new_col = ip->cur_columns - 1;
  264.     if (new_row >= ip->cur_rows)
  265.         new_row = 0;
  266.     if (new_col >= ip->cur_columns)
  267.         new_col = 0;
  268.         
  269.     /* Now let's go through the list to see if there is an entry with this
  270.      * new position
  271.      */
  272.     for (tmp = ip->first; tmp != NULL; tmp = tmp->next)
  273.     {
  274.         if (tmp->row == new_row && tmp->col == new_col)
  275.         {
  276.         got_it = TRUE;
  277.         break;
  278.         }
  279.     }
  280.     }
  281.  
  282.     if (!got_it)
  283.     {
  284.     fprintf (stderr, 
  285.          "%s:  unable to find window (%d, %d) in icon manager\n", 
  286.          ProgramName, new_row, new_col);
  287.     return;
  288.     }
  289.  
  290.     /* raise the frame so the icon manager is visible */
  291.     if (ip->twm_win->mapped) {
  292.     XRaiseWindow(dpy, ip->twm_win->frame);
  293.     XWarpPointer(dpy, None, tmp->icon, 0,0,0,0, 5, 5);
  294.     } else {
  295.     if (tmp->twm->title_height) {
  296.         int tbx = Scr->TBInfo.titlex;
  297.         int x = tmp->twm->highlightx;
  298.         XWarpPointer (dpy, None, tmp->twm->title_w, 0, 0, 0, 0,
  299.               tbx + (x - tbx) / 2,
  300.               Scr->TitleHeight / 4);
  301.     } else {
  302.         XWarpPointer (dpy, None, tmp->twm->w, 0, 0, 0, 0, 5, 5);
  303.     }
  304.     }
  305. }
  306.  
  307. /***********************************************************************
  308.  *
  309.  *  Procedure:
  310.  *    JumpIconManager - jump from one icon manager to another,
  311.  *        possibly even on another screen
  312.  *
  313.  *  Inputs:
  314.  *    dir    - one of the following:
  315.  *            F_NEXTICONMGR    - go to the next icon manager 
  316.  *            F_PREVICONMGR    - go to the previous one
  317.  *
  318.  ***********************************************************************
  319.  */
  320.  
  321. void JumpIconManager(dir)
  322.     register int dir;
  323. {
  324.     IconMgr *ip, *tmp_ip = NULL;
  325.     int got_it = FALSE;
  326.     ScreenInfo *sp;
  327.     int screen;
  328.  
  329.     if (!Active) return;
  330.  
  331.  
  332. #define ITER(i) (dir == F_NEXTICONMGR ? (i)->next : (i)->prev)
  333. #define IPOFSP(sp) (dir == F_NEXTICONMGR ? &(sp->iconmgr) : sp->iconmgr.lasti)
  334. #define TEST(ip) if ((ip)->count != 0 && (ip)->twm_win->mapped) \
  335.          { got_it = TRUE; break; }
  336.  
  337.     ip = Active->iconmgr;
  338.     for (tmp_ip = ITER(ip); tmp_ip; tmp_ip = ITER(tmp_ip)) {
  339.     TEST (tmp_ip);
  340.     }
  341.  
  342.     if (!got_it) {
  343.     int origscreen = ip->scr->screen;
  344.     int inc = (dir == F_NEXTICONMGR ? 1 : -1);
  345.  
  346.     for (screen = origscreen + inc; ; screen += inc) {
  347.         if (screen >= NumScreens)
  348.           screen = 0;
  349.         else if (screen < 0)
  350.           screen = NumScreens - 1;
  351.  
  352.         sp = ScreenList[screen];
  353.         if (sp) {
  354.         for (tmp_ip = IPOFSP (sp); tmp_ip; tmp_ip = ITER(tmp_ip)) {
  355.             TEST (tmp_ip);
  356.         }
  357.         }
  358.         if (got_it || screen == origscreen) break;
  359.     }
  360.     }
  361.  
  362. #undef ITER
  363. #undef IPOFSP
  364. #undef TEST
  365.  
  366.     if (!got_it) {
  367.     XBell (dpy, 0);
  368.     return;
  369.     }
  370.  
  371.     /* raise the frame so it is visible */
  372.     XRaiseWindow(dpy, tmp_ip->twm_win->frame);
  373.     if (tmp_ip->active)
  374.     XWarpPointer(dpy, None, tmp_ip->active->icon, 0,0,0,0, 5, 5);
  375.     else
  376.     XWarpPointer(dpy, None, tmp_ip->w, 0,0,0,0, 5, 5);
  377. }
  378.  
  379. /***********************************************************************
  380.  *
  381.  *  Procedure:
  382.  *    AddIconManager - add a window to an icon manager
  383.  *
  384.  *  Inputs:
  385.  *    tmp_win    - the TwmWindow structure
  386.  *
  387.  ***********************************************************************
  388.  */
  389.  
  390. WList *AddIconManager(tmp_win)
  391.     TwmWindow *tmp_win;
  392. {
  393.     WList *tmp;
  394.     int h;
  395.     unsigned long valuemask;        /* mask for create windows */
  396.     XSetWindowAttributes attributes;    /* attributes for create windows */
  397.     IconMgr *ip;
  398.  
  399.     tmp_win->list = NULL;
  400.  
  401.     if (tmp_win->iconmgr || tmp_win->transient || Scr->NoIconManagers)
  402.     return NULL;
  403.  
  404.     if (LookInList(Scr->IconMgrNoShow, tmp_win->full_name, &tmp_win->class))
  405.     return NULL;
  406.     if (Scr->IconManagerDontShow &&
  407.     !LookInList(Scr->IconMgrShow, tmp_win->full_name, &tmp_win->class))
  408.     return NULL;
  409.     if ((ip = (IconMgr *)LookInList(Scr->IconMgrs, tmp_win->full_name,
  410.         &tmp_win->class)) == NULL)
  411.     ip = &Scr->iconmgr;
  412.  
  413.     tmp = (WList *) malloc(sizeof(WList));
  414.     tmp->iconmgr = ip;
  415.     tmp->next = NULL;
  416.     tmp->active = FALSE;
  417.     tmp->down = FALSE;
  418.  
  419.     InsertInIconManager(ip, tmp, tmp_win);
  420.  
  421.     tmp->twm = tmp_win;
  422.  
  423.     tmp->fore = Scr->IconManagerC.fore;
  424.     tmp->back = Scr->IconManagerC.back;
  425.     tmp->highlight = Scr->IconManagerHighlight;
  426.  
  427.     GetColorFromList(Scr->IconManagerFL, tmp_win->full_name, &tmp_win->class,
  428.     &tmp->fore);
  429.     GetColorFromList(Scr->IconManagerBL, tmp_win->full_name, &tmp_win->class,
  430.     &tmp->back);
  431.     GetColorFromList(Scr->IconManagerHighlightL, tmp_win->full_name,
  432.     &tmp_win->class, &tmp->highlight);
  433.  
  434.     h = Scr->IconManagerFont.height + 10;
  435.     if (h < (siconify_height + 4))
  436.     h = siconify_height + 4;
  437.  
  438.     ip->height = h * ip->count;
  439.     tmp->me = ip->count;
  440.     tmp->x = -1;
  441.     tmp->y = -1;
  442.     
  443.     valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor);
  444.     attributes.background_pixel = tmp->back;
  445.     attributes.border_pixel = tmp->back;
  446.     attributes.event_mask = (KeyPressMask | ButtonPressMask |
  447.                  ButtonReleaseMask | ExposureMask |
  448.                  EnterWindowMask | LeaveWindowMask);
  449.     attributes.cursor = Scr->IconMgrCursor;
  450.     tmp->w = XCreateWindow (dpy, ip->w, 0, 0, (unsigned int) 1, 
  451.                 (unsigned int) h, (unsigned int) 0, 
  452.                 CopyFromParent, (unsigned int) CopyFromParent,
  453.                 (Visual *) CopyFromParent, valuemask, &attributes);
  454.  
  455.  
  456.     valuemask = (CWBackPixel | CWBorderPixel | CWEventMask | CWCursor);
  457.     attributes.background_pixel = tmp->back;
  458.     attributes.border_pixel = Scr->Black;
  459.     attributes.event_mask = (ButtonReleaseMask| ButtonPressMask |
  460.                  ExposureMask);
  461.     attributes.cursor = Scr->ButtonCursor;
  462.     tmp->icon = XCreateWindow (dpy, tmp->w, 5, (int) (h - siconify_height)/2,
  463.                    (unsigned int) siconify_width,
  464.                    (unsigned int) siconify_height,
  465.                    (unsigned int) 0, CopyFromParent,
  466.                    (unsigned int) CopyFromParent,
  467.                    (Visual *) CopyFromParent,
  468.                    valuemask, &attributes);
  469.  
  470.     ip->count += 1;
  471.     PackIconManager(ip);
  472.     XMapWindow(dpy, tmp->w);
  473.  
  474.     XSaveContext(dpy, tmp->w, IconManagerContext, (caddr_t) tmp);
  475.     XSaveContext(dpy, tmp->w, TwmContext, (caddr_t) tmp_win);
  476.     XSaveContext(dpy, tmp->w, ScreenContext, (caddr_t) Scr);
  477.     XSaveContext(dpy, tmp->icon, TwmContext, (caddr_t) tmp_win);
  478.     XSaveContext(dpy, tmp->icon, ScreenContext, (caddr_t) Scr);
  479.     tmp_win->list = tmp;
  480.  
  481.     if (!ip->twm_win->icon)
  482.     {
  483.     XMapWindow(dpy, ip->w);
  484.     XMapWindow(dpy, ip->twm_win->frame);
  485.     }
  486.  
  487.     return (tmp);
  488. }
  489.  
  490. /***********************************************************************
  491.  *
  492.  *  Procedure:
  493.  *    InsertInIconManager - put an allocated entry into an icon 
  494.  *        manager
  495.  *
  496.  *  Inputs:
  497.  *    ip    - the icon manager pointer
  498.  *    tmp    - the entry to insert
  499.  *
  500.  ***********************************************************************
  501.  */
  502.  
  503. void InsertInIconManager(ip, tmp, tmp_win)
  504.     IconMgr *ip;
  505.     WList *tmp;
  506.     TwmWindow *tmp_win;
  507. {
  508.     WList *tmp1;
  509.     int added;
  510.     int (*compar)() = (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1);
  511.  
  512.     added = FALSE;
  513.     if (ip->first == NULL)
  514.     {
  515.     ip->first = tmp;
  516.     tmp->prev = NULL;
  517.     ip->last = tmp;
  518.     added = TRUE;
  519.     }
  520.     else if (Scr->SortIconMgr)
  521.     {
  522.     for (tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next)
  523.     {
  524.         if ((*compar)(tmp_win->icon_name, tmp1->twm->icon_name) < 0)
  525.         {
  526.         tmp->next = tmp1;
  527.         tmp->prev = tmp1->prev;
  528.         tmp1->prev = tmp;
  529.         if (tmp->prev == NULL)
  530.             ip->first = tmp;
  531.         else
  532.             tmp->prev->next = tmp;
  533.         added = TRUE;
  534.         break;
  535.         }
  536.     }
  537.     }
  538.  
  539.     if (!added)
  540.     {
  541.     ip->last->next = tmp;
  542.     tmp->prev = ip->last;
  543.     ip->last = tmp;
  544.     }
  545. }
  546.  
  547. void RemoveFromIconManager(ip, tmp)
  548.     IconMgr *ip;
  549.     WList *tmp;
  550. {
  551.     if (tmp->prev == NULL)
  552.     ip->first = tmp->next;
  553.     else
  554.     tmp->prev->next = tmp->next;
  555.  
  556.     if (tmp->next == NULL)
  557.     ip->last = tmp->prev;
  558.     else
  559.     tmp->next->prev = tmp->prev;
  560. }
  561.  
  562. /***********************************************************************
  563.  *
  564.  *  Procedure:
  565.  *    RemoveIconManager - remove a window from the icon manager
  566.  *
  567.  *  Inputs:
  568.  *    tmp_win    - the TwmWindow structure
  569.  *
  570.  ***********************************************************************
  571.  */
  572.  
  573. void RemoveIconManager(tmp_win)
  574.     TwmWindow *tmp_win;
  575. {
  576.     IconMgr *ip;
  577.     WList *tmp;
  578.  
  579.     if (tmp_win->list == NULL)
  580.     return;
  581.  
  582.     tmp = tmp_win->list;
  583.     tmp_win->list = NULL;
  584.     ip = tmp->iconmgr;
  585.  
  586.     RemoveFromIconManager(ip, tmp);
  587.     
  588.     XDeleteContext(dpy, tmp->icon, TwmContext);
  589.     XDeleteContext(dpy, tmp->icon, ScreenContext);
  590.     XDestroyWindow(dpy, tmp->icon);
  591.     XDeleteContext(dpy, tmp->w, IconManagerContext);
  592.     XDeleteContext(dpy, tmp->w, TwmContext);
  593.     XDeleteContext(dpy, tmp->w, ScreenContext);
  594.     XDestroyWindow(dpy, tmp->w);
  595.     ip->count -= 1;
  596.     free((char *) tmp);
  597.  
  598.     PackIconManager(ip);
  599.  
  600.     if (ip->count == 0)
  601.     {
  602.     XUnmapWindow(dpy, ip->twm_win->frame);
  603.     }
  604.  
  605. }
  606.  
  607. void ActiveIconManager(active)
  608.     WList *active;
  609. {
  610.     active->active = TRUE;
  611.     Active = active;
  612.     Active->iconmgr->active = active;
  613.     DrawIconManagerBorder(active);
  614. }
  615.  
  616. void NotActiveIconManager(active)
  617.     WList *active;
  618. {
  619.     active->active = FALSE;
  620.     DrawIconManagerBorder(active);
  621. }
  622.  
  623. void DrawIconManagerBorder(tmp)
  624.     WList *tmp;
  625. {
  626.     {
  627.     XSetForeground(dpy, Scr->NormalGC, tmp->fore);
  628.         XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 2, 2,
  629.         tmp->width-5, tmp->height-5);
  630.  
  631.     if (tmp->active && Scr->Highlight)
  632.         XSetForeground(dpy, Scr->NormalGC, tmp->highlight);
  633.     else
  634.         XSetForeground(dpy, Scr->NormalGC, tmp->back);
  635.  
  636.     XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 0, 0,
  637.         tmp->width-1, tmp->height-1);
  638.     XDrawRectangle(dpy, tmp->w, Scr->NormalGC, 1, 1,
  639.         tmp->width-3, tmp->height-3);
  640.     }
  641. }
  642.  
  643. /***********************************************************************
  644.  *
  645.  *  Procedure:
  646.  *    SortIconManager - sort the dude
  647.  *
  648.  *  Inputs:
  649.  *    ip    - a pointer to the icon manager struture
  650.  *
  651.  ***********************************************************************
  652.  */
  653.  
  654. void SortIconManager(ip)
  655.     IconMgr *ip;
  656. {
  657.     WList *tmp1, *tmp2;
  658.     int done;
  659.     int (*compar)() = (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1);
  660.  
  661.     if (ip == NULL)
  662.     ip = Active->iconmgr;
  663.  
  664.     done = FALSE;
  665.     do
  666.     {
  667.     for (tmp1 = ip->first; tmp1 != NULL; tmp1 = tmp1->next)
  668.     {
  669.         if ((tmp2 = tmp1->next) == NULL)
  670.         {
  671.         done = TRUE;
  672.         break;
  673.         }
  674.         if ((*compar)(tmp1->twm->icon_name, tmp2->twm->icon_name) > 0)
  675.         {
  676.         /* take it out and put it back in */
  677.         RemoveFromIconManager(ip, tmp2);
  678.         InsertInIconManager(ip, tmp2, tmp2->twm);
  679.         break;
  680.         }
  681.     }
  682.     }
  683.     while (!done);
  684.     PackIconManager(ip);
  685. }
  686.  
  687. /***********************************************************************
  688.  *
  689.  *  Procedure:
  690.  *    PackIconManager - pack the icon manager windows following
  691.  *        an addition or deletion
  692.  *
  693.  *  Inputs:
  694.  *    ip    - a pointer to the icon manager struture
  695.  *
  696.  ***********************************************************************
  697.  */
  698.  
  699. void PackIconManager(ip)
  700.     IconMgr *ip;
  701. {
  702.     int newwidth, i, row, col, maxcol,  colinc, rowinc, wheight, wwidth;
  703.     int new_x, new_y;
  704.     int savewidth;
  705.     WList *tmp;
  706.  
  707.     wheight = Scr->IconManagerFont.height + 10;
  708.     if (wheight < (siconify_height + 4))
  709.     wheight = siconify_height + 4;
  710.  
  711.     wwidth = ip->width / ip->columns;
  712.  
  713.     rowinc = wheight;
  714.     colinc = wwidth;
  715.  
  716.     row = 0;
  717.     col = ip->columns;
  718.     maxcol = 0;
  719.     for (i = 0, tmp = ip->first; tmp != NULL; i++, tmp = tmp->next)
  720.     {
  721.     tmp->me = i;
  722.     if (++col >= ip->columns)
  723.     {
  724.         col = 0;
  725.         row += 1;
  726.     }
  727.     if (col > maxcol)
  728.         maxcol = col;
  729.  
  730.     new_x = col * colinc;
  731.     new_y = (row-1) * rowinc;
  732.  
  733.     /* if the position or size has not changed, don't touch it */
  734.     if (tmp->x != new_x || tmp->y != new_y ||
  735.         tmp->width != wwidth || tmp->height != wheight)
  736.     {
  737.         XMoveResizeWindow(dpy, tmp->w, new_x, new_y, wwidth, wheight);
  738.  
  739.         tmp->row = row-1;
  740.         tmp->col = col;
  741.         tmp->x = new_x;
  742.         tmp->y = new_y;
  743.         tmp->width = wwidth;
  744.         tmp->height = wheight;
  745.     }
  746.     }
  747.     maxcol += 1;
  748.  
  749.     ip->cur_rows = row;
  750.     ip->cur_columns = maxcol;
  751.     ip->height = row * rowinc;
  752.     if (ip->height == 0)
  753.         ip->height = rowinc;
  754.     newwidth = maxcol * colinc;
  755.     if (newwidth == 0)
  756.     newwidth = colinc;
  757.  
  758.     XResizeWindow(dpy, ip->w, newwidth, ip->height);
  759.  
  760.     savewidth = ip->width;
  761.     if (ip->twm_win)
  762.       SetupWindow (ip->twm_win,
  763.            ip->twm_win->frame_x, ip->twm_win->frame_y,
  764.            newwidth, ip->height + ip->twm_win->title_height, -1);
  765.     ip->width = savewidth;
  766. }
  767.